package general;

import in.Daemon;

import java.io.File;
import java.io.FileReader;
import java.text.MessageFormat;
import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import out.Sender;
import storage.Storage;

/**
 * Главный класс контроля и запуска
 * 
 * @author Last G
 * 
 */
public class Main
{
	private static final Logger logger = LoggerFactory.getLogger(Main.class);
	private static in.Daemon in;
	private static out.Sender out;
	private static storage.Storage storage;
	private static Properties configs = new LoggableProperties(
			getDefaultConfigurations());
	private static String configurationFile = "ef-server.conf";
	/**
	 * Message queue for main class
	 */
	public static final ConcurrentLinkedQueue<Message> Messages = new ConcurrentLinkedQueue<Message>();

	/**
	 * Главный класс
	 * 
	 * @param args
	 *            командная строка
	 */
	public static void main(String[] args)
	{
		System.out.println("Exploitfarm Server");
		System.out.println("Compiled from SVN: $Rev: 130 $");
		
		try
		{
			File c = new File(configurationFile);
			if (!c.exists())
			{
				throw new RuntimeException(MessageFormat.format(
						"Configuration file: \"{0}\" not exists", new Object[]
							{ configurationFile }));
			}
			configs.load(new FileReader(c));
		} catch (Exception e)
		{
			logger.error("Can't load configuration file", e);
			System.exit(1);
		}
		try
		{
			logger.debug("Server is starting");
			storage = new Storage(configs);
			logger.debug("Storage created");
			in = new Daemon(configs);
			logger.debug("Daemon created");
			in.start();
			logger.debug("Daemon started");
			out = new Sender(configs);
			logger.debug("Sender created");
			out.start();
			logger.debug("Sender started");

			monitor();
		} catch (Exception e)
		{
			logger.error("Server stopped cause smth bad occured", e);
			System.exit(1);
		}
	}

	private static void monitor()
	{
		while (true)
		{
			if (Messages.isEmpty())
			{
				try
				{
					Thread.sleep(400);
				} catch (InterruptedException e)
				{
					logger.warn("Main thread has been iterrupted");
				}
			} else
			{
				proceedMessage();
			}
		}
	}

	private static void proceedMessage()
	{
		while (!Messages.isEmpty())
		{
			Message msg = Messages.poll();
			logger.debug(msg.getInfo());
		}
	}

	private final static Properties getDefaultConfigurations()
	{
		Properties def = new Properties();

		// Storage
		def.setProperty("storage.type", "memory");

		// Sender
		def.setProperty("sender.type", "default");
		def.setProperty("sender.jury_port", "31337");
		def.setProperty("sender.timeout", "2000");
		def.setProperty("sender.max_flags_per_thread", "25");
		def.setProperty("sender.max_threads", "5");
		def.setProperty("sender.delay", "1000");

		// IN
		def.setProperty("in.port", "62674");
		return def;
	}

	/**
	 * @return storage
	 */
	public static storage.Storage getStorage()
	{
		return Main.storage;
	}
}
